define(function(require, exports, module) {
  "use strict";
  var Base = require("smartartBase");
  var PositionDetectorModel = require("./model");

  module.exports = Base.SmartartBaseView.extend({
    initialize: function(config, options) {
      this.positionDetectorModel = new PositionDetectorModel({});

      // 创建widget的时候
      var isFirstCreate = !config.itemId;

      if (isFirstCreate) {
        config.position = {top: 200, left: 100}; 
        this.isFirstCreate = true;
      }
      Base.SmartartBaseView.prototype.initialize.apply(this, arguments);

      if (isFirstCreate) {
        this.firstInit();
      } else {
        this.init();
      }

      this.isFirstCreate = false;
      this.fitSize();
    },

    // 初次创建控件组时的初始化
    firstInit: function() {
      this.initModelData();
      this.createItems(2);
      this.createPositionDetectors(1);
      this.layout();
      this.makeSignalSlot();
    },

    addPositionDetectorAnswer: function() {
      var answers = this.positionDetectorModel.get("answers") || [];
      var positionDetectors = this.getWidgetsByType("positionDetector");
      if (positionDetectors.length <= answers.length) return;
      answers.push({detectorAnswer: [{widgetId: null}]});
      this.setData("answers", answers);
      this.positionDetectorModel.set("answers", answers);
      this.updateAnswer();
    },

    removeExtraPositionDetectorAnswer: function() {
      var answers = this.positionDetectorModel.get("answers") || [];
      var positionDetectors = this.getWidgetsByType("positionDetector");
      if (answers.length <= positionDetectors.length) return;
      for (var i = 0, length = answers.length - positionDetectors.length; i < length; i++) {
        answers.pop();
      }
      this.setData("answers", answers);
      this.positionDetectorModel.set("answers", answers);
    },

    // 已有控件组的初始化
    init: function() {
      this.initModelData();
    },

    initModelData: function() {
      this.positionDetectorModel.set("checkingMode", this.getData("checkingMode") || "resetPosition");
      this.positionDetectorModel.set("typeOfItem", this.getData("typeOfItem") || "image");
      this.positionDetectorModel.set("numberOfPositions", this.getData("numberOfPositions") || 1);
      this.positionDetectorModel.set("numberOfItems", this.getData("numberOfItems") || 2);
      this.positionDetectorModel.set("answers", this.getData("answers") || []);
    },

    // 创建位置检测控件
    createPositionDetector: function() {
      var positionDetectorWidget;
      positionDetectorWidget = this.create("item", {type: "positionDetector"});
      positionDetectorWidget.model.set({
          hasSignalSlot: true,
          hasDelete: false
        });
      this.addChild(positionDetectorWidget);
      this.updatePositionDetectorDisplayName();
      this.addPositionDetectorAnswer();
      return positionDetectorWidget;
    },

    createImageItem: function() {
      var imageWidget;
      imageWidget = this.create("item", {type: "image"});
      imageWidget.model.set({
        hasSignalSlot: false,
        hasDelete: false
      });
      imageWidget.dataChange({name: "draggable", value: true}, imageWidget.itemId, true);
      this.addChild(imageWidget);
      this.updateItemDisplayName();
      return imageWidget;
    },

    createShapeItem: function() {
      var shapeWidget;
      shapeWidget = this.create("item", {type: "shapes"});
      shapeWidget.model.set({
        hasSignalSlot: false,
        hasDelete: false
      });
      shapeWidget.dataChange({name: "draggable", value: true}, shapeWidget.itemId, true);
      this.addChild(shapeWidget);
      this.updateItemDisplayName();
      return shapeWidget;
    },

    createRichtextItem: function() {
      var richtextWidget;
      richtextWidget = this.create("item", {type: "richtext"});
      richtextWidget.model.set({
        hasSignalSlot: false,
        hasDelete: false
      });
      richtextWidget.dataChange({name: "draggable", value: true}, richtextWidget.itemId, true);
      richtextWidget.model.set("size", {width: 140, height: 50});
      this.addChild(richtextWidget);
      this.updateItemDisplayName();
      return richtextWidget;
    },

    updateItemDisplayName: function() {
      var widgetType = this.positionDetectorModel.get("typeOfItem") || "image";
      var items = this.getWidgetsByType(widgetType);
      var smartartDisplayName = this.model.get("displayName");
      items.forEach(function(item, index) {
        item.model.set("displayName", smartartDisplayName + "-项目" + (index + 1));
      });
    },

    updatePositionDetectorDisplayName: function() {
      var positionDetectors = this.getWidgetsByType("positionDetector");
      var smartartDisplayName = this.model.get("displayName");
      positionDetectors.forEach(function(detector, index) {
        detector.model.set("displayName", smartartDisplayName + "-位置" + (index + 1));
      });
    },

    createItem: function() {
      var widgetType = this.positionDetectorModel.get("typeOfItem");
      if (!widgetType) return null;

      var item;

      if (widgetType === "image") {
        item = this.createImageItem();
      } else if (widgetType === "shapes") {
        item = this.createShapeItem();
      } else {
        item = this.createRichtextItem();
      }

      if (this.isFirstCreate) return item;

      var rightMostItem = this.findRightmostItem();
      var rightMostItemPosition;
      if (rightMostItem) {
        rightMostItemPosition = rightMostItem.model.get("position");
        this.setWidgetPosition(item, {top: rightMostItemPosition.top, left: rightMostItemPosition.left + 20});
      }

      return item;
    },

    createItems: function(num) {
      var numberOfItems = num || this.positionDetectorModel.get("numberOfItems");
      for (var i = 0; i < numberOfItems; i++) {
        this.createItem();
      }
    },

    removeItems: function(num) {
      var widgetType = this.positionDetectorModel.get("typeOfItem");
      var widgets = this.getWidgetsByType(widgetType);
      num = num || widgets.length;
      num = num > widgets.length ? widgets.length : num;

      var length = widgets.length;
      var i = 0;
      while (i++ < num) {
        widgets[length - i].remove();
      }
    },

    createPositionDetectors: function(num) {
      var numberOfPositions = num || this.positionDetectorModel.get("numberOfPositions");
      var positionDetector;
      var rightMostPositionDetector;
      var rightMostPositionDetectorPosition;
      for (var i = 0; i < numberOfPositions; i++) {
        positionDetector = this.createPositionDetector();
        if (this.isFirstCreate) continue;
        rightMostPositionDetector = this.findRightmostPositionDetector();
        if (rightMostPositionDetector) {
          rightMostPositionDetectorPosition = rightMostPositionDetector.model.get("position");
          this.setWidgetPosition(positionDetector, {top: rightMostPositionDetectorPosition.top, left: rightMostPositionDetectorPosition.left + 20});
        }
      }
    },

    removePositionDetectors: function(num) {
      var widgets = this.getWidgetsByType("positionDetector");
      num = num || widgets.length;
      num = num > widgets.length ? widgets.length : num;

      var length = widgets.length;
      var i = 0;
      while (i++ < num) {
        widgets[length - i].remove();
      }
      this.removeExtraPositionDetectorAnswer();
    },

    /**
     * 仅创建控件组的时候会做 layout
     */
    layout: function() {
      this.layoutPositionDetectors();
      this.layoutItems();
      this.fitSize();
    },

    layoutPositionDetectors: function() {
      // positionDetector控件默认大小 198 x 160
      var positionDetectors = this.getWidgetsByType("positionDetector");
      var top = 0;
      var left = 0;

      for (var i = 0, length = positionDetectors.length; i < length; i++) {
        this.setWidgetPosition(positionDetectors[i], {top: top, left: left});
        left += 198 + 20;
      }
    },

    layoutItems: function() {
      var widgetType = this.positionDetectorModel.get("typeOfItem");
      var itemWidgets = this.getWidgetsByType(widgetType);
      var top = 200;
      var left = 0;

      for (var i = 0, length = itemWidgets.length; i < length; i++) {
        this.setWidgetPosition(itemWidgets[i], {top: top, left: left});
        left += 198 + 20;
      }
    },

    findRightmostItem: function() {
      var widgetType = this.positionDetectorModel.get("typeOfItem");
      if (!widgetType) { return null; }

      var widgets = this.getWidgetsByType(widgetType);

      if (widgets.length === 0) { return null; }

      var widget = widgets[0];

      for (var i = 1, length = widgets.length; i < length; i++) {
        if (widgets[i].model.get("position").left > widget.model.get("position").left) {
          widget = widgets[i];
        }
      }

      return widget;
    },

    findRightmostPositionDetector: function() {
      var positionDetectors = this.getWidgetsByType("positionDetector");

      if (positionDetectors.length === 0) { return null; }

      var p = positionDetectors[0];

      for (var i = 1, length = positionDetectors.length; i < length; i++) {
        if (positionDetectors[i].model.get("position").left > p.model.get("position").left) {
          p = positionDetectors[i];
        }
      }

      return p;
    },

    getWidgetByItemId: function(itemId) {
      return this.children.filter(function(child) {
        return child.itemId === itemId;
      })[0];
    },

    getWidgetsByType: function(type) {
      return this.children.filter(function(child) {
        return child.model.get("type") === type;
      });
    },

    setWidgetPosition: function(item, pos) {
      var widget;
      if (typeof item === "string") {
        widget = this.getWidgetByItemId(itemId);
      } else {
        widget = item;
      }
      widget.model.set('position', pos);
      widget.trigger('fitSize');
    },

    // hook: 当智能控件组的子控件被移除时，该方法被调用
    removeChild: function(view) {
      Base.SmartartBaseView.prototype.removeChild.apply(this, [view]);
      if (this.isRemovingSmartart) return;
    },

    // hook: 当智能控件组被移除时，该方法被调用，removeChild也会因此被逐一调用
    remove: function() {
      this.isRemovingSmartart = true;
      Base.SmartartBaseView.prototype.remove.apply(this, arguments);
      this.isRemovingSmartart = false;
    },

    setData: function(type, value) {
      var data = this.getSelfData();
      data[type] = value;
      this.setSelfData(data);
    },

    getData: function(type) {
      var data = this.getSelfData();
      return data[type];
    },

    changeNumberOfItems: function(delta) {
      if (delta < 0) {
        this.removeItems(-delta);
      } else {
        this.createItems(delta);
      }
    },

    changeNumberOfPositions: function(delta) {
      if (delta < 0) {
        this.removePositionDetectors(-delta);
      } else {
        this.createPositionDetectors(delta);
      }
    },

    updatePositionDetectorCheckingMode: function() {
      var checkingMode = this.positionDetectorModel.get("checkingMode");
      var positionDetectors = this.getWidgetsByType("positionDetector");
      positionDetectors.forEach(function(positionDetector) {
        positionDetector.dataChange({name: "view", value: checkingMode}, positionDetector.itemId, true);
      });
    },

    updateAnswer: function() {
      var answers = this.positionDetectorModel.get("answers");
      var positionDetectors = this.getWidgetsByType("positionDetector");
      for (var i = 0, length = positionDetectors.length; i < length; i++) {
        if (answers[i]) {
          positionDetectors[i].dataChange({name: "answer", value: answers[i].detectorAnswer}, positionDetectors[i].itemId, true);
        } else {
          break;
        }
      }
    },

    refreshUI: function(data) {
      var shouldUpdateAnswer = false;
      var orginalData = data;

      data = this.formatAttributeData(data);

      if (data.checkingMode && data.checkingMode !== this.positionDetectorModel.get("checkingMode")) {
        this.positionDetectorModel.set("checkingMode", data.checkingMode);
        this.updatePositionDetectorCheckingMode();
        this.makeSignalSlot();
      }

      if (data.typeOfItem && data.typeOfItem !== this.positionDetectorModel.get("typeOfItem")) {
        this.removeItems();
        this.positionDetectorModel.set("typeOfItem", data.typeOfItem);
        this.createItems();
        this.layoutItems();
        this.fitSize();
        this.makeSignalSlot();
      }

      if (data.numberOfItems && data.numberOfItems !== this.positionDetectorModel.get("numberOfItems")) {
        this.changeNumberOfItems(data.numberOfItems - this.positionDetectorModel.get("numberOfItems"));
        this.positionDetectorModel.set("numberOfItems", data.numberOfItems);
        // this.layoutItems();
        this.makeSignalSlot();
        this.fitSize();
      }

      if (data.numberOfPositions && data.numberOfPositions !== this.positionDetectorModel.get("numberOfPositions")) {
        this.changeNumberOfPositions(data.numberOfPositions - this.positionDetectorModel.get("numberOfPositions"));
        this.positionDetectorModel.set("numberOfPositions", data.numberOfPositions);
        // this.layoutPositionDetectors();
        this.makeSignalSlot();
        this.fitSize();
      }

      if (data.answers) {
        this.positionDetectorModel.set("answers", data.answers);
        this.updateAnswer();
      }

      Base.SmartartBaseView.prototype.refreshUI.apply(this, [orginalData]);
    },
    formatAttributeData: function(data) {
      var obj = {};
      data.forEach(function(item) {
        obj[item.name] = item.value;
      });
      return obj;
    },

    makeSignalSlot: function() {
      var signals = [];
      var positionDetectors = this.getWidgetsByType("positionDetector");
      var itemWidgetType = this.positionDetectorModel.get("typeOfItem");
      var items = this.getWidgetsByType(itemWidgetType);
      var self = this;

      items.forEach(function(item) {
        positionDetectors.forEach(function(positionDetector) {
          signals.push([item.itemId, "positionChanged." + itemWidgetType, positionDetector.itemId, "checkPosition"]);
        });
      });

      positionDetectors.forEach(function(positionDetector) {
        items.forEach(function(item) {
          signals.push([positionDetector.itemId, "kickout.positionDetector", item.itemId, "resetPosition"]);
          signals.push([positionDetector.itemId, "widgetIn.positionDetector", item.itemId, "setCenterPoint"]);
          if (self.positionDetectorModel.get("checkingMode") === "resetPosition") {
            signals.push([positionDetector.itemId, "wrong.positionDetector", item.itemId, "resetPosition"]);
          }
          // } else {
          //   // signals.push([positionDetector.itemId, "wrong.positionDetector", item.itemId, "setCenterPoint"]);
          // }
        });
      });

      // send signal-slot to signal-slot manager
      this.sendSignalSlot(signals);
    }
  });

});
